import { defineStore, createPinia } from 'pinia'
import { computed, ref } from 'vue'
import { App } from 'vue'
import localforage from 'localforage'
import { qiankunActions } from '@/utils/qiankun/Action'
import { sourceUrl } from '@/config/baseConfig'

import { loginStatusApi, getUserInfoApi } from '@/request/api/master'
import { getProjectPageListAPi } from '@/request/api/project'
// import { downloadFileApi } from '@/request/api/master'
import {
  sseConnectEnduringApi,
  getNotReadMessageCountApi,
} from '@/request/api/chatHistory'

const pinia = createPinia()

// 封装路由初始化方法
export const initStore = (app: App<Element>) => {
  app.use(pinia)
}

// 在 Setup Store 中：
// ref() 就是 state 属性
// computed() 就是 getters
// function() 就是 actions

//
//
// 联网状态
export const useOnlineStatusStore = defineStore('onlineStatus', () => {
  const onlineStatus = ref<boolean>(true)
  const refresh = ref<string>()

  function setStatus(value: boolean) {
    onlineStatus.value = value
  }
  function getStatus() {
    return onlineStatus.value
  }

  // 给出联网情况提示变化
  function setRefresh() {
    refresh.value = new Date().toString()
  }

  return {
    onlineStatus: computed(() => onlineStatus.value),
    refresh: computed(() => refresh.value),
    setStatus,
    getStatus,
    setRefresh,
  }
})

//
//
// 登录状态
export const useLoginStore = defineStore('login', () => {
  const status = ref<false | true>(false)

  function setStatusFalse() {
    status.value = false
  }

  async function getStatus() {
    const { connectEnduringSSE, closeConnect, getNotReadMessageCount } =
      useEnduringSseStore()

    const res = await loginStatusApi()

    if (res.code !== 200) {
      closeConnect()
      useProjectStore().resetProjectList()
      return (status.value = false)
    }

    // 登录时建立 SSE 持久连接
    connectEnduringSSE()
    setTimeout(() => getNotReadMessageCount(), 1000)

    status.value = res.data
    return res.data
  }

  return {
    status: computed(() => status.value),
    setStatusFalse,
    getStatus,
  }
})

//
//
// 用户信息
export const useUserInfoStore = defineStore('userInfo', () => {
  const id = ref<string>('')
  const email = ref<string>('')
  const avatar = ref<string>('')
  const account = ref<string>('')
  const nickname = ref<string>('nickname')
  const description = ref<string>('')

  // 获取用户信息
  async function getUserInfo() {
    const res = await getUserInfoApi()
    if (res?.code !== 200) {
      reset()
      return console.error('状态管理，获取用户信息失败！')
    }

    id.value = res.data.id
    email.value = res.data.email
    avatar.value = res.data.avatar
    account.value = res.data.account
    nickname.value = res.data.nickname
    description.value = res.data.description

    if (res.data.account) initInfoCache()

    useLocalUserCacheStore().setUserDir(account.value)
    qiankunActions.setGlobalState({
      userInfo: {
        id: id.value,
        account: account.value,
        nickname: nickname.value,
        avatar: res.data?.avatar,
      },
    })
  }

  function reset() {
    id.value = ''
    email.value = ''
    // avatar.value = ''
    account.value = ''
    // nickname.value = 'nickname'
    description.value = ''
  }

  //  初始化一下用户信息缓存
  const initInfoCache = async () => {
    const d: userInfoCacheItf = {
      id: id.value,
      account: account.value,
      nickname: nickname.value,
      avatar: { path: sourceUrl + avatar.value, data: '' },
      description: '',
      email: '',
    }
    localforage.setItem('userInfoCache', d)
  }

  // 下载头像图片文件
  // const downloadFile = async (path: string) => {
  //   const res = await downloadFileApi(path)
  //   const avatarData = `data:image/jpeg;base64,${res.data}`
  //   let data: userInfoCacheItf = await localforage.getItem('userInfoCache')
  //   data.avatar.path = path
  //   data.avatar.data = avatarData
  //   localforage.setItem('userInfoCache', data)
  // }

  return {
    id: computed(() => id.value),
    email: computed(() => email.value),
    avatar: computed(() => avatar.value),
    account: computed(() => account.value),
    nickname: computed(() => nickname.value),
    description: computed(() => description.value),
    getUserInfo,
    reset,
  }
})

//
//
// 用户本地缓存信息
export const useLocalUserCacheStore = defineStore('localUserCache', () => {
  // 在本地设置用户的一些信息
  // 在用户登录获取信息时设置一下
  function setUserDir(account) {
    ;(window as any).localFile.createUserDir(account)
  }

  return {
    setUserDir: setUserDir,
  }
})

//
//
// 主题色
export const useThemeStore = defineStore('theme', () => {
  // 当前主题
  const theme = ref<string>('')
  // 主题选项
  const option = ref<{ [key: string]: Function }>({
    'theme-default': () => theme0,
    'theme-blue': () => theme1,
    'theme-pink': () => theme2,
  })
  // element UI 按钮颜色
  const buttonColor = ref<string>('')

  // 主题配置
  // 灰色系
  const theme0: themeItf = {
    '--theme-background': '#FAFCFF',
    '--theme-header': '#fcd3d3',
    '--theme-aside': '#fef0f0',
    '--theme-footer': '#fcd3d3',
    '--theme-active-label': '#F56C6C',
    '--theme-hover-label': '#f89898',
    '--theme-scrollbar-thumb': '#fab6b6',
    '--theme-scrollbar-button': '#f89898',
  }
  // 蓝色系
  const theme1: themeItf = {
    '--theme-background': '#FAFCFF',
    '--theme-header': '#E0E7F8',
    '--theme-aside': '#EDF3FF',
    '--theme-footer': '#E0E7F8',
    '--theme-active-label': '#671ddf',
    '--theme-hover-label': '#a577fc',
    '--theme-scrollbar-thumb': '#B4B4E6',
    '--theme-scrollbar-button': '#9B9DC1',
  }
  // 粉色系
  const theme2: themeItf = {
    '--theme-background': '#FAFCFF',
    '--theme-header': '#FFE8E8',
    '--theme-aside': '#FFF4F4',
    '--theme-footer': '#FFE8E8',
    '--theme-active-label': '#E67F6E',
    '--theme-hover-label': '#F79FAA',
    '--theme-scrollbar-thumb': '#FFDADA',
    '--theme-scrollbar-button': '#F5C8C8',
  }

  // 设置主题
  function setTheme(value: string) {
    theme.value = value
    changeTheme()
  }
  // 改变主题
  function changeTheme() {
    const currentTheme = option.value[theme.value]()
    const arr: string[] = Object.keys(currentTheme)
    buttonColor.value = currentTheme['--theme-hover-label']

    arr?.map((item) => {
      document.documentElement.style.setProperty(item, currentTheme[item])
    })
  }

  return {
    option: computed(() => option.value),
    theme: computed(() => theme.value),
    buttonColor: computed(() => buttonColor.value),
    setTheme,
  }
})

//
//
// 用户所拥有的项目列表
export const useProjectStore = defineStore('project', () => {
  // 项目列表
  const projects = ref<projectStoreItf[]>([])
  // 当前项目id
  const projectId = ref<string>('')

  function setProjectId(id: string) {
    projectId.value = id
  }

  // 页码
  const page = ref<number>(1)

  // 获取用户的项目列表
  async function getProjectList() {
    if (!window.localStorage.getItem('token')) return (projectId.value = '')

    const res = await getProjectPageListAPi({ page: page.value, pageSize: 10 })
    if (res.code !== 200) {
      projects.value = []
      return (projectId.value = '')
    }

    // 将获取到的项目数据进行休整，合并
    const tempList: projectStoreItf[] = res.data.records.map((item) => {
      return { projectId: item.id, title: item.title }
    })
    projects.value = [...projects.value, ...tempList]

    //  是否获取完所有的项目
    if (projects.value.length >= res.data.total) {
      // 缓存项目列表
      initProjectListCache(projects.value)

      // 分页获取完所有项目后
      // 如果没有选定项目，项目id不存在则默认选择第一个项目
      if (!projectId.value)
        return (projectId.value = projects.value[0].projectId)

      // 项目id存在的话进行过滤判断，获取的项目中是否有此id
      // 没有的话则默认选择第一个项目
      const l = projects.value.filter(
        (item) => item.projectId === projectId.value
      )
      if (l.length === 0) projectId.value = projects.value[0].projectId
    } else {
      // 没有则进行递归获取
      page.value = page.value + 1
      getProjectList()
    }
  }

  // 重新获取项目列表
  function resetProjectList() {
    page.value = 0
    projects.value = []
    getProjectList()
  }

  // 初始化一下用户项目列表缓存
  const initProjectListCache = async (list: projectStoreItf[]) => {
    const init = () => {
      let obj: projectListCacheItf = {}
      list.map((item) => {
        const d = { projectId: item.projectId, title: item.title }
        obj[item.projectId] = d
      })

      return obj
    }

    const prefix = useUserInfoStore().account
    if (!prefix) return
    localforage.setItem(prefix + '-projectListCache', init())
  }

  return {
    projectId: computed(() => projectId.value),
    projects: computed(() => projects.value),
    setProjectId,
    getProjectList,
    resetProjectList,
  }
})

//
//
// SSE 连接
export const useEnduringSseStore = defineStore('enduringSSE', () => {
  let source: EventSource
  const notReadCount = ref<string | number>(0)

  //建立 SSE 持久连接
  function connectEnduringSSE() {
    if (source) return

    source = sseConnectEnduringApi()

    source.onopen = function (event) {
      console.log('\x1b[1m\x1b[34m%s\x1b[0m', 'enduring SSE 连接成功', event)
    }

    source.onmessage = function (event) {
      // to to something…
      console.log(
        '\x1b[1m\x1b[32m%s\x1b[0m',
        'enduring SSE 接收信息',
        event.data
      )
    }

    source.onerror = function (event) {
      // 监听错误
      console.info('\x1b[1m\x1b[31m%s\x1b[0m', 'enduring SSE  错误', event)
    }

    source.addEventListener('refreshToken', function (e) {
      console.log('enduring SSE 监听 refreshToken 事件成功 ', e.data)
      window.localStorage.setItem('token', e.data.split('"')[1])
    })
    source.addEventListener('notReadCount', function (e) {
      console.log('enduring SSE 监听 notReadCount 事件成功 ', e.data)
      if (e.data >= 100) notReadCount.value = '···'
      else notReadCount.value = e.data
    })
  }

  //关闭连接
  function closeConnect() {
    source.close()
    source = null // 清除 source 变量
    console.log('\x1b[1m\x1b[31m%s\x1b[0m', 'enduring SSE 已关闭')
  }

  //获取未读消息，登录时检查一下，
  function getNotReadMessageCount() {
    getNotReadMessageCountApi()
  }

  return {
    notReadCount: computed(() => notReadCount.value),
    closeConnect: closeConnect,
    connectEnduringSSE: connectEnduringSSE,
    getNotReadMessageCount: getNotReadMessageCount,
  }
})
